package org.springonrails.model;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;


public class Entity 
{
	private String javaName;
	private String tableName;
	private String viewLabel;
	private boolean hasDateField;
	boolean hasPrimaryKey;
	private List<Attribute> attributes;
	private List<String> primaryKeyColumnNames;
	private List<Attribute> primaryKeyColumns;
	private List<Attribute> nonprimaryKeyColumns;
	private SecureRandom secureRandom = null;
	private String methods;
	private List<Relationship> relationships;
	
	public String toString()
	{
		StringBuffer buffer = new StringBuffer();
		buffer.append("<entity javaName=\"").append(javaName).append("\"");
		if(tableName!=null) buffer.append("  tableName=\"").append(tableName).append("\"");
		if(viewLabel!=null) buffer.append("  viewLabel=\"").append(viewLabel).append("\"");		
		buffer.append(">\r\n");
		
		for(Attribute att: attributes)
		{
			buffer.append(att.toString());
		}	
		
		for (Relationship relationship : relationships) {
			 buffer.append(relationship.toString());
			 buffer.append("\r\n");
		}
		
		if(methods!=null){
		  buffer.append("<methods><![CDATA[\r\n");
		  buffer.append(methods);
		  buffer.append("\r\n");
		  buffer.append("]]></methods>\r\n");
		}
		buffer.append("</entity>\r\n");
		return buffer.toString();
	}
	
	public Entity()
	{
		this.attributes  = new ArrayList<Attribute>();
		this.primaryKeyColumnNames = new ArrayList<String>();
		this.primaryKeyColumns = new ArrayList<Attribute>();
		this.nonprimaryKeyColumns = new ArrayList<Attribute>();	
		this.relationships = new ArrayList<Relationship>();
		
	}
	
	
	public boolean isHasRelationships()
	{
		return this.relationships.size()>0;
	}
	
	public void addRelationship(Relationship r)
	{
		this.relationships.add(r);
	}
	
	
	public List<Relationship> getRelationships() {
		return relationships;
	}

	public Attribute getHibernatePrimaryKeyColumn()
	{
		if(this.primaryKeyColumns.size()==0)
		{
			throw new RuntimeException("Spring-On-Rails does not support without key for ORM type of Hibernate");
		}		
		return this.primaryKeyColumns.get(0);
	}
	
	
	public boolean isHasMethods()
	{
		return (this.methods!=null);
	}
	
	
	public String getMethods() {
		return methods;
	}




	public void setMethods(String methods) {
		this.methods = methods;
	}




	public String getUniqueId()
	{
		String ret = null;
		if(secureRandom==null) {
			byte[] seed = (javaName==null)?"random".getBytes():javaName.getBytes();		
			secureRandom = new SecureRandom(seed);
		}
		ret = String.valueOf(Math.abs(secureRandom.nextInt()));			
		return ret;
	}
	
	
	public String getViewLabel() {
		return (viewLabel==null || viewLabel.trim().length()==0)?javaName:viewLabel;
	}



	public void setViewLabel(String viewLabel) {
		this.viewLabel = viewLabel;
	}



	public String getNormalizedJavaName()
	{
		return this.javaName.toLowerCase().charAt(0)+this.javaName.substring(1);
	}
	
	public boolean isHasPrimaryKey() {
		return hasPrimaryKey;
	}

	public boolean isPrimaryKeyIntegerType()
	{
		return (primaryKeyColumns.size()==1 && 
				(primaryKeyColumns.get(0).getJavaType().equalsIgnoreCase("int")
				|| primaryKeyColumns.get(0).getJavaType().equalsIgnoreCase("long")));
	}
	
	public boolean isPrimaryKeyStringType()
	{
		return (primaryKeyColumns.size()==1 && 
				(primaryKeyColumns.get(0).getJavaType().equalsIgnoreCase("string")));
	}
	
	public String getSinglePrimaryKeyJavaType()
	{
		return primaryKeyColumns.get(0).getJavaType();
	}

	public void setHasPrimaryKey(boolean hasPrimaryKey) {
		this.hasPrimaryKey = hasPrimaryKey;
	}



	public void addAttribute(Attribute att)
	{
		if(att.isPrimaryKey()){
			this.primaryKeyColumns.add(att);
			primaryKeyColumnNames.add(att.getColumnName());
			this.hasPrimaryKey = true;
		}else{
			this.nonprimaryKeyColumns.add(att);
		}
		if(att.isDateType())this.hasDateField = true;
		this.attributes.add(att);
	}
	
		
	public boolean isHasDateField() {
		return hasDateField;
	}

	public void setHasDateField(boolean hasDateField) {
		this.hasDateField = hasDateField;
	}

	public List<Attribute> getAttributes() {
		return attributes;
	}
	
	
	
	public List<Attribute> getNonprimaryKeyColumns() {
		return nonprimaryKeyColumns;
	}

	public void setNonprimaryKeyColumns(List<Attribute> nonprimaryKeyColumns) {
		this.nonprimaryKeyColumns = nonprimaryKeyColumns;
	}

	public void setAttributes(List<Attribute> attributes) {
		for (Attribute attribute : attributes) {
			if(attribute.isPrimaryKey()){
				this.hasPrimaryKey = true;
				this.primaryKeyColumns.add(attribute);
				primaryKeyColumnNames.add(attribute.getColumnName());	
			
			}else{
				this.nonprimaryKeyColumns.add(attribute);
			}
			if(attribute.isDateType())this.hasDateField = true;
		}
		this.attributes = attributes;
	}
	
	
	public String getJavaName() {
		return javaName;
	}
	public void setJavaName(String javaName) {
		this.javaName = javaName;
	}
	public String getTableName() {
		return tableName;
	}
	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public List<String> getPrimaryKeyColumnNames() {
		return primaryKeyColumnNames;
	}

	public void setPrimaryKeyColumnNames(List<String> primaryKeyColumnNames) {
		this.primaryKeyColumnNames = primaryKeyColumnNames;
	}

	public List<Attribute> getPrimaryKeyColumns() {
		return primaryKeyColumns;
	}

	public void setPrimaryKeyColumns(List<Attribute> primaryKeyColumns) {
		this.primaryKeyColumns = primaryKeyColumns;
	}
}
